/*

Frequency of use: 1 2 [3] 4 5 MEDIUM 

Short:
    Bridge allows two implementations to vary independently. In this case, the 
implementations of message and recipient are independent, but combine to 
output "Hello world!"

Long:
    The bridge pattern is a design pattern used in software engineering which is 
meant to "decouple an abstraction from its implementation so that the two can 
vary independently" [1]. The bridge uses encapsulation, aggregation, and can use 
inheritance to separate responsibilities into different classes.
When a class varies often, the features of object-oriented programming become 
very useful because changes to a program's code can be made easily with minimal 
prior knowledge about the program. The bridge pattern is useful when both the 
class as well as what it does varies. The class itself can be thought of as the 
implementation and what the class can do as the abstraction. The bridge pattern 
can also be thought of as two layers of abstraction.
Variant: The implementation can be decoupled even more by deferring the presence 
of the implementation to the point where the abstraction is utilized.

Information sources:
 - http://calumgrant.net/patterns/index.html
 - http://en.wikipedia.org/wiki/Bridge_pattern
 - http://www.dofactory.com/Patterns/Patterns.aspx
*/

#include <iostream>
#include <string>

class Message
{
public:
	virtual ~Message() { }
	virtual void send_to(const std::string &)=0;
};

class Recipient
{
public:
	virtual ~Recipient() { }
	virtual void send(Message &)=0;
};

class Hello : public Message
{
public:
	void send_to(const std::string & name)
	{
		std::cout << "Hello " << name << "!" << std::endl;
	};
};

class World : public Recipient
{
public:
	void send(Message & msg)
	{
		msg.send_to("world");
	};
};

void hello_world(Message & msg, Recipient & recipient)
{
	recipient.send(msg);
}

int main()
{
	Hello hello;
	World world;
	hello_world(hello, world);
	return 0;
}

